// Copyright (c) 2011 Blue Onion Software, All rights reserved
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using BlueOnionSoftware.Bloget.Properties;

namespace BlueOnionSoftware.Bloget
{
    /// <summary>
    /// The BlogetArchive control shows the months where a blog entry was made.
    /// It is a common element found most blog engines. While interesting, the
    /// index control is much more powerful and comprehensive.
    /// </summary>
    [Designer(typeof (BlogetArchiveDesigner))]
    public class BlogetArchive : Bloget
    {
        private int _length = 10;
        private string _more = "More...";
        private ITemplate _archiveTemplate;

        [Browsable(false)]
        [Description("Archive template")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof (ArchiveContainerControl))]
        public ITemplate ArchiveTemplate
        {
            get { return _archiveTemplate; }
            set { _archiveTemplate = value; }
        }

        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue("10")]
        [Localizable(false)]
        public int Length
        {
            get { return _length; }
            set { _length = (value > 0) ? value : _length; }
        }

        [Bindable(false)]
        [Category("Appearance")]
        [DefaultValue("10")]
        [Localizable(true)]
        public string More
        {
            get { return _more; }
            set { _more = value; }
        }

        protected override void CreateChildControls()
        {
            var count = _length;

            if (_archiveTemplate == null)
            {
                Controls.Add(new LiteralControl(@"<ul class=""bloget-archive-list"">"));
            }

            foreach (var archiveDate in Blog.ArchiveDates())
            {
                if (count-- <= 0)
                {
                    break;
                }
                if (_archiveTemplate != null)
                {
                    var archiveContainer = new ArchiveContainerControl(this, Blog, archiveDate);
                    _archiveTemplate.InstantiateIn(archiveContainer);
                    Controls.Add(archiveContainer);
                }
                else
                {
                    Controls.Add(new LiteralControl("<li>"));
                    var link = new HyperLink
                    {
                        Text = string.Format(CultureInfo.CurrentCulture, "{0} ({1})",
                                             archiveDate.Date.ToString("Y", CultureInfo.CurrentCulture),
                                             archiveDate.Count),
                        NavigateUrl = BuildQueryString(Mode.Blog, null, 0, null, null, archiveDate.Date, null)
                    };
                    Controls.Add(link);
                    Controls.Add(new LiteralControl("</li>" + Environment.NewLine));
                }
            }

            if (_archiveTemplate == null)
            {
                if (string.IsNullOrEmpty(_more) == false)
                {
                    Controls.Add(new LiteralControl("<li>"));
                    var link = new HyperLink
                    {
                        Text = _more,
                        NavigateUrl = BuildQueryString(Mode.Index, null, 0, null, null, DateTime.MinValue, null)
                    };
                    Controls.Add(link);
                    Controls.Add(new LiteralControl("</li>" + Environment.NewLine));
                }
                Controls.Add(new LiteralControl("</ul>" + Environment.NewLine));
            }
        }
    }

    /// <summary>
    /// ArchiveContainerControl defines what can be referenced in the Archive
    /// template
    /// </summary>
    public class ArchiveContainerControl : BlogContainerControl
    {
        private readonly ArchiveDate _archiveDate;

        public ArchiveContainerControl(Bloget bloget, Blog blog, ArchiveDate archiveDateArg)
            : base(bloget, blog)
        {
            _archiveDate = archiveDateArg;
        }

        public DateTime ArchiveDate
        {
            get { return _archiveDate.Date; }
        }

        public int ArchiveCount
        {
            get { return _archiveDate.Count; }
        }

        public string ArchiveLink
        {
            get { return Bloget.BuildQueryString(Mode.Blog, null, 0, null, null, _archiveDate.Date, null); }
        }
    }

    internal class BlogetArchiveDesigner : ControlDesigner
    {
        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods")]
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            SetViewFlags(ViewFlags.TemplateEditing, true);
        }

        public override string GetDesignTimeHtml()
        {
            return "<span>" + Resources.ArchiveViewDesignTimeHtml + "</span>";
        }

        public override bool AllowResize
        {
            get { return true; }
        }

        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods")]
        public override TemplateGroupCollection TemplateGroups
        {
            get
            {
                var collection = new TemplateGroupCollection();
                var control = (Bloget) Component;
                var group = new TemplateGroup("Bloget");
                var template = new TemplateDefinition(this, "ArchiveTemplate", control, "ArchiveTemplate", true);
                group.AddTemplateDefinition(template);
                collection.Add(group);
                return collection;
            }
        }
    }
}